package com.yys.excel.yysexcel.utils;

import cn.hutool.core.collection.ListUtil;
import cn.hutool.core.img.ImgUtil;
import cn.hutool.core.io.FileUtil;
import cn.hutool.core.io.IoUtil;
import cn.hutool.core.util.IdUtil;
import cn.hutool.core.util.StrUtil;
import cn.hutool.db.Entity;
import cn.hutool.http.HttpUtil;
import com.aliyun.oss.*;
import com.aliyun.oss.model.DeleteObjectsRequest;
import com.aliyun.oss.model.DeleteObjectsResult;
import com.aliyun.oss.model.GeneratePresignedUrlRequest;
import com.aliyun.oss.model.GetObjectRequest;
import com.yys.excel.yysexcel.utils.dbUtil.DbUtil;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.UnsupportedEncodingException;
import java.net.URL;
import java.net.URLDecoder;
import java.util.Date;
import java.util.List;

/*
oss工具类
 */
public class AttachUtils {
    private static final String endpoint = "oss-cn-shenzhen.aliyuncs.com";

    private static final String accessKeyId = "LTAI4G3frvygyx5HkTYNMecq";

    private static final String accessKeySecret = "dUbJorTf7kD2l357Of8QDu7s4VIOg5";

    private static final String bucketName = "gzhtsz";

    private static final String filePath = "E:/testFile/damagePhoto";

    public static void main(String[] args) {
        List<String> of = ListUtil.of("test/6f16bfa026106c2846851e19c5adcff4_1.jpg", "test/testpp.png");
        deleteFiles(of);
    }

    //删除存储在本地的图片文件
    public static void delAllFile() {
        FileUtil.del(filePath);
    }

    /**
     * 生成未压缩图片文件,通过pid获取图片
     *
     * @param pid
     * @param isFirst 是否为上传的第一张
     * @return
     */
    public static File fileByPid(String pid, boolean isFirst) {
        String sql = "select * from ATTACH where pid = ? and wjlx in ('0','1') order by ID";
        List<Entity> querys = DbUtil.querys(sql, pid);
        int size = querys.size();
        if (size > 0) {
            Entity entity = null;
            if (isFirst) {
                //取本次上传的第一张照片
                entity = querys.get(0);
            } else {
                //取本次上传的最后一张照片
                entity = querys.get(size - 1);
            }
            return downloadFile(entity.getStr("CCDZ") + "/" + entity.getStr("CCMC"));
        }
        return null;
    }

    /**
     * 通过pid获取文件字节
     *
     * @param pid     pid
     * @param isFirst 是否为第一张图片
     * @return {@link byte[]}
     */
    public static byte[] fileByteByPid(String pid, boolean isFirst) {
        String sql = "select * from ATTACH where pid = ? and wjlx in ('0','1') order by ID";
        List<Entity> querys = DbUtil.querys(sql, pid);
        int size = querys.size();
        if (size > 0) {
            Entity entity = null;
            if (isFirst) {
                //取本次上传的第一张照片
                entity = querys.get(0);
            } else {
                //取本次上传的最后一张照片
                entity = querys.get(size - 1);
            }
            return getPicByte(entity.getStr("CCDZ") + "/" + entity.getStr("CCMC"));
        }
        return null;
    }

    /**
     * 生成未压缩图片访问地址,通过pid获取图片
     *
     * @param pid
     * @param isFirst 是否为上传的第一张
     * @return
     */
    public static String fileUrlByPid(String pid, boolean isFirst) {
        String sql = "select * from ATTACH where pid = ? and wjlx in ('0','1') order by ID";
        List<Entity> querys = DbUtil.querys(sql, pid);
        int size = querys.size();
        if (size > 0) {
            Entity entity = null;
            if (isFirst) {
                //取本次上传的第一张照片
                entity = querys.get(0);
            } else {
                //取本次上传的最后一张照片
                entity = querys.get(size - 1);
            }
            return getPicPath(entity.getStr("CCDZ") + "/" + entity.getStr("CCMC"));
        }
        return null;
    }

    /**
     * 将本地文件上传至阿里云
     *
     * @param filePath    本地文件路径
     * @param ossFilePath 阿里云文件路径
     */
    public void getOssClient(String filePath, String ossFilePath) {
        // 创建OSSClient实例。
        OSS ossClient = getOssClient();
        File file = FileUtil.file(filePath);
        ossClient.putObject(bucketName, ossFilePath, file);
        // 关闭OSSClient。
        ossClient.shutdown();
        //本地文件删除
        FileUtil.del(file);
    }

    /**
     * inputstream 转 文件
     *
     * @param filepath filepath
     * @return {@link File}
     */
    public static File inputstreamToFile(String filepath) {
        InputStream picPathStream = getPicPathStream(filepath);
        if (picPathStream != null) {
            FileUtil.mkdir(filePath);
            String fileName = FileUtil.getName(filepath);
            //获取该文件的本地路径
            String path = filePath + "/" + fileName;
            return FileUtil.writeFromStream(picPathStream, path);
        }
        return null;
    }

    /**
     * 删除一个文件
     *
     * @param filePath 填写文件完整路径。文件完整路径中不能包含Bucket名称。
     * @return boolean
     */
    public static boolean deleteFileOne(String filePath) {
        OSS ossClient = getOssClient();
        try {
            ossClient.deleteObject(bucketName, filePath);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            return false;
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
        return true;
    }

    /**
     * 删除多个文件
     *
     * @param filePaths 填写需要删除的多个文件完整路径。文件完整路径中不能包含Bucket名称。
     */
    public static void deleteFiles(List<String> filePaths) {
        OSS ossClient = getOssClient();
        try {
            DeleteObjectsResult deleteObjectsResult = ossClient.deleteObjects(new DeleteObjectsRequest(bucketName).withKeys(filePaths).withEncodingType("url"));
            List<String> deletedObjects = deleteObjectsResult.getDeletedObjects();
            try {
                for (String obj : deletedObjects) {
                    String deleteObj = URLDecoder.decode(obj, "UTF-8");
                    System.out.println(deleteObj);
                }
            } catch (UnsupportedEncodingException e) {
                e.printStackTrace();
            }
        } catch (OSSException oe) {
            System.out.println("Caught an OSSException, which means your request made it to OSS, "
                    + "but was rejected with an error response for some reason.");
            System.out.println("Error Message:" + oe.getErrorMessage());
            System.out.println("Error Code:" + oe.getErrorCode());
            System.out.println("Request ID:" + oe.getRequestId());
            System.out.println("Host ID:" + oe.getHostId());
        } catch (ClientException ce) {
            System.out.println("Caught an ClientException, which means the client encountered "
                    + "a serious internal problem while trying to communicate with OSS, "
                    + "such as not being able to access the network.");
            System.out.println("Error Message:" + ce.getMessage());
        } finally {
            if (ossClient != null) {
                ossClient.shutdown();
            }
        }
    }

    private static OSS getOssClient() {
        return new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
    }

    //oss下载文件到本地
    public static File downloadFile(String filepath) {
        FileUtil.mkdir(filePath);
        String fileName = FileUtil.getName(filepath);
        //获取该文件的本地路径
        String path = filePath + "/" + fileName;
        // 创建OSSClient实例。
        OSS ossClient = getOssClient();
        ossClient.getObject(new GetObjectRequest(bucketName, filepath), new File(path));
        // 关闭OSSClient。
        ossClient.shutdown();
        File file = FileUtil.file(path);
        File ysFile = null;
        try {
            ysFile = ysImg(file);
        } catch (Exception e) {
            System.out.println("压缩出错图片链接：" + filepath);
        }
        return ysFile;
    }

    //生成未压缩图片访问地址
    public static String getPicPath(String filepath) {
        // 创建OSSClient实例。
        OSS ossClient = getOssClient();

        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, filepath, expiration);


        // 关闭OSSClient。
        ossClient.shutdown();
        return url.toString();
    }

    //将oss图片转成byte[]数组
    public static byte[] getPicByte(String filepath) {
        InputStream picPathStream = getPicFile_cut(filepath);
        if (picPathStream != null) {
            return IoUtil.readBytes(picPathStream);
        }
        return null;
    }

    //生成压缩图片输入流
    public static InputStream getPicFile_cut(String filepath) {
        //"test/upload/2019.jpg"
        String style = "image/auto-orient,1/resize,p_40/quality,q_40";
        String objectName = filepath;

        // 创建OSSClient实例。
        OSS ossClient = getOssClient();

        // 设置URL过期时间为1小时。
        Date expiration = new Date(new Date().getTime() + 3600 * 1000);
        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, objectName, HttpMethod.GET);
        req.setExpiration(expiration);
        req.setProcess(style);

        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        //URL url = ossClient.generatePresignedUrl(bucketName, objectName, expiration);
        URL url = ossClient.generatePresignedUrl(req);
        InputStream in = null;
        try {
            in = url.openStream();

        } catch (IOException e) {
            e.printStackTrace();
        }
        // 关闭OSSClient。
        ossClient.shutdown();
        return in;
    }

    //生成未压缩图片stream流
    public static InputStream getPicPathStream(String filepath) {
        // 创建OSSClient实例。
        OSS ossClient = getOssClient();

        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(bucketName, filepath, expiration);
        InputStream in = null;
        try {
            in = url.openStream();
        } catch (IOException e) {
            e.printStackTrace();
        } finally {
            // 关闭OSSClient。
            ossClient.shutdown();
        }
        return in;
    }

    //生成未压缩图片文件
    public static File getPicFile(String filepath) {
        String picPath = getPicPath(filepath);
        File file = null;
        try {
            file = HttpUtil.downloadFileFromUrl(picPath, filePath);
        } catch (Exception e) {
            System.out.println("出错的图片链接:" + picPath);
        }
        return file;
    }

    /**
     * 按照样式压缩图片
     *
     * @param filepath
     * @return
     */
    public static String getPicPath_Cut(String filepath, String style) {
        if (StrUtil.isEmptyIfStr(style)) {
            return getPicPath(filepath);
        }
        // 创建OSSClient实例。
        OSS ossClient = getOssClient();

        // 设置URL过期时间为1小时。
        Date expiration = new Date(System.currentTimeMillis() + 3600 * 1000);
        GeneratePresignedUrlRequest req = new GeneratePresignedUrlRequest(bucketName, filepath, HttpMethod.GET);
        req.setExpiration(expiration);
        req.setProcess(style);

        // 生成以GET方法访问的签名URL，访客可以直接通过浏览器访问相关内容。
        URL url = ossClient.generatePresignedUrl(req);

        // 关闭OSSClient。
        ossClient.shutdown();
        return url.toString();
    }

    //压缩图片
    public static File ysImg(File imageFile) {
        File outFile = new File(filePath + "/" + IdUtil.simpleUUID() + ".jpg");
        ImgUtil.compress(imageFile, outFile, 0.5f);
        return outFile;
    }

    /**
     * 按照百分比压缩
     *
     * @param filepath
     * @return
     */
    public static String getPicPath_Cut(String filepath) {
        String style = "image/auto-orient,1/resize,p_60/quality,q_70";
        return getPicPath_Cut(filepath, style);
    }

    /**
     * 按照尺寸压缩 128*128
     *
     * @param filepath
     * @return
     */
    public static String getPicPath_Cut_128(String filepath) {
        String style = "image/resize,m_lfit,w_128/quality,q_100";
        return getPicPath_Cut(filepath, style);
    }

    /**
     * 按照尺寸压缩 640*640
     *
     * @param filepath
     * @return
     */
    public static String getPicPath_Cut_640(String filepath) {
        String style = "image/resize,m_lfit,w_640/quality,q_100";
        return getPicPath_Cut(filepath, style);
    }
}
